package main

import (
	"fmt"
)


/**
 * slice : 对数组的抽象  动态数组
 * 定义： var identifier []type
 * 测试切片功能 （不定长度）
 */
func main() {

	var numbers []int

	/* 允许追加空切片 */
   numbers = append(numbers, 0)
   printSlice(numbers)

   /* 向切片添加一个元素 */
   numbers = append(numbers, 1)
   printSlice(numbers)

   /* 同时添加多个元素 */
   numbers = append(numbers, 2,3,4)
   printSlice(numbers)

}


/* 切片的扩容遵循的规则:o 代表原容量 n 代表扩容后的容量
	 1.如果追加的元素超过了原切片容量,但小于原容量的2倍并且小于1024个字节: o < n < 2 * o && n < 1024
	 那么会进行2倍扩容,如果超过了1024,会进行1.25倍扩容
	 2.如果追加的元素超过了原容量的2倍,即原容量扩充两倍也无法容纳下所有元素: n > 2 * o,直接使用系统预估的容量
	 3.以上两种情况得到的新容量,都会根据切片类型的字节长度,算出新容量的内存,然后向上取整,选取最接近的一个系统定义的类型长度
	 然后除以切片类型长度得到最终切片的容量,下面是go预定义的一些类型的字节长度:
	  class  bytes/obj  bytes/span  objects  tail waste  max waste
	      1          8        8192     1024           0     87.50%
	      2         16        8192      512           0     43.75%
	      3         32        8192      256           0     46.88%
	      4         48        8192      170          32     31.52%
	      5         64        8192      128           0     23.44%
	      6         80        8192      102          32     19.07%
	      7         96        8192       85          32     15.95%
	      8        112        8192       73          16     13.56%
	      9        128        8192       64           0     11.72%
	     10        144        8192       56         128     11.82%
	     ...
	     65      28672       57344        2           0      4.91%
	     66      32768       32768        1           0     12.50%
	 */
func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}